package com.cosmoplat.xikai.business.service.impl;

import com.cosmoplat.xikai.business.domain.BaseDeliveryInfo;
import com.cosmoplat.xikai.business.domain.BaseDispatchTask;
import com.cosmoplat.xikai.business.domain.BaseMaterial;
import com.cosmoplat.xikai.business.domain.BaseWorkOrder;
import com.cosmoplat.xikai.business.domain.dto.mes.CloseAlarmByCheckedMesDTO;
import com.cosmoplat.xikai.business.domain.dto.mes.MaterialUpdateByMesDTO;
import com.cosmoplat.xikai.business.domain.dto.mes.ProductionPlanByMesDTO;
import com.cosmoplat.xikai.business.enums.DeviceParamsEnum;
import com.cosmoplat.xikai.business.enums.DeviceRunStatusEnum;
import com.cosmoplat.xikai.business.enums.DeviceTricolourLightEnum;
import com.cosmoplat.xikai.business.service.*;
import com.cosmoplat.xikai.common.enums.DelFlagEnum;
import com.cosmoplat.xikai.common.enums.business.TaskPlanStatusEnum;
import com.cosmoplat.xikai.common.exception.ServiceException;
import com.cosmoplat.xikai.common.utils.bean.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * @ClassName MesCallServiceImpl
 * @Description mes 调用服务实现类
 * @Author wdf
 * @Date 2025/1/7
 */
@Slf4j
@Service
public class MesCallServiceImpl implements MesCallService {

    @Autowired
    private BaseMaterialService materialService;

    @Autowired
    private BaseWorkOrderService workOrderService;

    @Autowired
    private BaseDispatchTaskService dispatchTaskService;

    @Autowired
    private BaseDeliveryInfoService deliveryInfoService;
    @Autowired
    private DeviceCallService deviceCallService;
    @Value("${device.code}")
    private String deviceCode;


    @Transactional
    @Override
    public boolean updateMaterial(MaterialUpdateByMesDTO material) {
        // 查是否已存在旧数据
        BaseMaterial baseMaterial = materialService.getByMesMaterialId(material.getMaterialId());

        if (material.getType() == null
                || material.getType() == MaterialUpdateByMesDTO.SyncType.ADD.getValue()
                || material.getType() == MaterialUpdateByMesDTO.SyncType.UPDATE.getValue()
        ) {
            // 新增
            if (baseMaterial == null) {
                baseMaterial = new BaseMaterial();
                BeanUtils.copyProperties(material, baseMaterial);
                baseMaterial.setId(null);
                baseMaterial.setIsDelete(DelFlagEnum.NORMAL.getCode());
                materialService.save(material);
            } else {
                // 已存在(逻辑删除)
                baseMaterial.setIsDelete(DelFlagEnum.DELETE.getCode());
                materialService.updateById(baseMaterial);
                baseMaterial = new BaseMaterial();
                BeanUtils.copyProperties(material, baseMaterial);
                baseMaterial.setId(null);
                baseMaterial.setIsDelete(DelFlagEnum.NORMAL.getCode());
                materialService.save(material);
            }
        } else if (material.getType() == MaterialUpdateByMesDTO.SyncType.DELETE.getValue()){
            baseMaterial.setIsDelete(DelFlagEnum.DELETE.getCode());
            materialService.updateById(baseMaterial);
        } else {
            // 错误
            throw new ServiceException("同步类型标识码错误");
        }
        return true;
    }

    @Transactional
    @Override
    public boolean productionPlan(ProductionPlanByMesDTO productionPlan) {
        BaseWorkOrder oldWorkOrder = workOrderService.getByMesOrderId(productionPlan.getOrderId());
        if (oldWorkOrder != null) {
            log.warn("下发了重复的订单");
            throw new ServiceException("下发了重复的订单");
            /*for (BaseDispatchTask dispatchTask : productionPlan.getDispatchTask()) {
                // 暂停逻辑
                String stopStatus = "stop";
                String runStatus = "Executing";
                BaseDispatchTask oldTask = dispatchTaskService.getByMesTaskId(dispatchTask.getTaskId());
                if (oldTask == null) {
                    log.warn("重复的订单,原有的任务不存在, {}" + dispatchTask);
                    continue;
                }
                if (dispatchTask.getTaskStatus().equals(stopStatus)) {
                    // 任务已完成，不更新暂停状态
                    if (oldTask.getTaskPlanStatus() == TaskPlanStatusEnum.FINISHED.getCode()) {
                        log.info("任务已完成，不更新暂停状态, taskNo={}", oldTask.getTaskNo());
                        continue;
                    }
                    oldTask.setTaskStatus(stopStatus);
                    // 保存当前的状态
                    oldTask.setLastTaskPlanStatus(oldTask.getTaskPlanStatus());
                    oldTask.setTaskPlanStatus(TaskPlanStatusEnum.PAUSE.getCode());

                    // 下发设备进行暂停控制 TODO

                } else if (dispatchTask.getTaskStatus().equals(runStatus)) {
                    oldTask.setTaskStatus(runStatus);
                    // 恢复之前的状态
                    oldTask.setTaskPlanStatus(oldTask.getLastTaskPlanStatus());
                    oldTask.setLastTaskPlanStatus(TaskPlanStatusEnum.FLAG.getCode());
                }
                dispatchTaskService.updateById(oldTask);
            }
            oldWorkOrder.setIsDelete(DelFlagEnum.DELETE.getCode());
            workOrderService.updateById(oldWorkOrder);*/
        }
        BaseWorkOrder workOrder = new BaseWorkOrder();
        BeanUtils.copyProperties(productionPlan, workOrder);
        workOrder.setId(null);
        workOrder.setIsDelete(DelFlagEnum.NORMAL.getCode());
        workOrderService.save(workOrder);
        // 保存新任务
        for (BaseDispatchTask task : productionPlan.getDispatchTask()) {
            BaseDispatchTask oldTask = dispatchTaskService.getByTaskId(task.getTaskId());
            if (oldTask != null) {
                // 该任务正在执行中
                if (TaskPlanStatusEnum.DOING.getCode().equals(oldTask.getTaskPlanStatus())) {
                    // TODO 确认需求逻辑如何处理
                    log.info("该任务正在执行中, taskNo={}", task.getTaskNo());
                    throw new ServiceException("该任务正在执行中, taskNo=" + task.getTaskNo());
                }
                // 该任务已暂停
                if (TaskPlanStatusEnum.PAUSE.getCode().equals(oldTask.getTaskPlanStatus())) {
                    // TODO 确认需求逻辑如何处理
                    log.info("该任务已暂停, taskNo={}", task.getTaskNo());
                    throw new ServiceException("该任务已暂停, taskNo=" + task.getTaskNo());
                }
                // 该任务已完成
                if (TaskPlanStatusEnum.FINISHED.getCode().equals(oldTask.getTaskPlanStatus())) {
                    // TODO 确认需求逻辑如何处理
                    log.info("该任务已完成, taskNo={}", task.getTaskNo());
                    throw new ServiceException("该任务已完成, taskNo=" + task.getTaskNo());
                }
                // 逻辑删除该任务
                oldTask.setIsDelete(DelFlagEnum.DELETE.getCode());
                dispatchTaskService.updateById(oldTask);
                // 逻辑删除该任务的物料
                List<BaseDeliveryInfo> deliveryList = deliveryInfoService.getListByTaskId(task.getTaskId());
                for (BaseDeliveryInfo deliveryInfo : deliveryList) {
                    deliveryInfo.setIsDelete(DelFlagEnum.DELETE.getCode());
                }
                deliveryInfoService.updateBatchById(deliveryList);
            }
            task.setOrderId(workOrder.getOrderId());
            task.setIsDelete(DelFlagEnum.NORMAL.getCode());
            task.setTaskPlanStatus(TaskPlanStatusEnum.UN_START.getCode());
            task.setCompletedQty(BigDecimal.ZERO);
            dispatchTaskService.save(task);

            // 保存配送信息
            for (BaseDeliveryInfo deliveryInfo : task.getDeliveryInfo()) {
                deliveryInfo.setIsDelete(DelFlagEnum.NORMAL.getCode());
                deliveryInfo.setTaskId(task.getTaskId());
                deliveryInfoService.save(deliveryInfo);
            }
        }
        return true;
    }

    @Override
    public boolean closeAlarmByChecked(CloseAlarmByCheckedMesDTO closeAlarmByChecked) {
        log.info("告警关闭：{}", closeAlarmByChecked);
        // 告警关闭三色灯
        if (!deviceCallService.sendCommand(deviceCode, DeviceParamsEnum.TRICOLOUR_LIGHT.getName(), DeviceTricolourLightEnum.TURN_OFF_THE_LIGHT.getCode())) {
            throw new ServiceException("下发设备关闭三色灯失败");
        }


        return true;
    }




}
